package com.google.memoryofaplace.controller;

import java.io.IOException;
import java.io.PrintWriter;
import java.nio.ByteBuffer;
import java.util.Date;
import java.util.Map;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.google.appengine.api.blobstore.BlobInfo;
import com.google.appengine.api.blobstore.BlobInfoFactory;
import com.google.appengine.api.blobstore.BlobKey;
import com.google.appengine.api.blobstore.BlobstoreService;
import com.google.appengine.api.blobstore.BlobstoreServiceFactory;
import com.google.appengine.api.files.AppEngineFile;
import com.google.appengine.api.files.FileService;
import com.google.appengine.api.files.FileServiceFactory;
import com.google.appengine.api.files.FileWriteChannel;
import com.google.appengine.api.images.Image;
import com.google.appengine.api.images.ImagesService;
import com.google.appengine.api.images.ImagesServiceFactory;
import com.google.appengine.api.images.Transform;
import com.google.appengine.repackaged.org.json.JSONObject;
import com.google.memoryofaplace.General;


public class Upload extends HttpServlet {
	private static final long serialVersionUID = 1L;
	private BlobstoreService blobstoreService = BlobstoreServiceFactory
			.getBlobstoreService();

	public void doPost(HttpServletRequest req, HttpServletResponse res)
			throws ServletException, IOException {

		int WIDTH = 345;
		int HEIGHT = 293;
		
		General.currentLocale = req.getLocale();

		res.setCharacterEncoding("UTF-8");
		res.setContentType("text/xml;charset=UTF-8");
		JSONObject jReturn = new JSONObject();
		PrintWriter out = res.getWriter();
		try {
			Map<String, BlobKey> blobs = blobstoreService.getUploadedBlobs(req);
			BlobKey blobKey = blobs.get("file");
			if (blobKey == null) {
				out.println("<?xml version=\"1.0\"?>");
				out.println("<response>");
				out.println("<desc>No image found</desc>");
				out.println("<date>" + General.formatDate(new Date()) + "</date>");
				out.println("<status>" + General.KO + "</status>");
				out.println("</response>");				
			} else {
				BlobInfo blobInfo = new BlobInfoFactory().loadBlobInfo(blobKey);
				byte[] bytes = blobstoreService.fetchData(blobKey, 0,
						blobInfo.getSize());
				String contentType = blobInfo.getContentType();
				long size = blobInfo.getSize();
				Date creation = blobInfo.getCreation();
				String fileName = blobInfo.getFilename();
				ImagesService imagesService = ImagesServiceFactory
						.getImagesService();
				Image image = ImagesServiceFactory.makeImage(bytes);
				int imageWidth = image.getWidth();
				int imageHeight = image.getHeight();
				
				Transform resize = ImagesServiceFactory.makeResize(345, 293);
				Image newImage = imagesService.applyTransform(resize, image);

				BlobKey blobKeyNewImage = writeFileBlobStore(newImage.getImageData(), blobInfo.getContentType(), fileName);
				BlobInfo blobInfoNewImage = new BlobInfoFactory().loadBlobInfo(blobKeyNewImage);

				String strServingUrl = imagesService.getServingUrl(blobKeyNewImage);
				if (General.isImage(contentType)) {
					out.println("<?xml version=\"1.0\"?>");
					out.println("<response>");
					out.println("<date>" + General.formatDate(new Date()) + "</date>");
					out.println("<status>" + General.OK + "</status>");
					
					out.println("<imageoriginal>");
					out.println("<size>" + size + "</size>");
					out.println("<creation>" + General.formatDate(creation) + "</creation>");
					out.println("<filename>" + fileName + "</filename>");
					out.println("<width>" + imageWidth + "</width>");
					out.println("<height>" + imageHeight + "</height>");					
					out.println("</imageoriginal>");
					
					out.println("<image>");					
					out.println("<size>" + blobInfoNewImage.getSize() + "</size>");
					out.println("<creation>" + General.formatDate(blobInfoNewImage.getCreation()) + "</creation>");
					out.println("<filename>" +  blobInfoNewImage.getFilename() + "</filename>");
					out.println("<width>" + WIDTH + "</width>");
					out.println("<height>" + HEIGHT + "</height>");
					out.println("<url>" + strServingUrl + "</url>");
					out.println("<thumbnailurl>" + strServingUrl + "=s60"+ "</thumbnailurl>");
					out.println("<key>" +  blobKeyNewImage.getKeyString() + "</key>");					
					out.println("</image>");
					
					out.println("</response>");	
						
					//borrar la imagen original subida
					blobstoreService.delete(blobKey);
				} else {
					jReturn = General.returnError("this is not an image");
					blobstoreService.delete(blobKey);
				}

			}
		} catch (Exception e) {
			jReturn = new JSONObject();
			jReturn = General.returnError(e.getMessage());
		}
		finally
		{
			out.close();
		}

		res.getWriter().print(jReturn.toString());

	}
	
	private BlobKey writeFileBlobStore(byte[] imageData, String contentType, String fileName) {
		  FileService fileService = FileServiceFactory.getFileService();
		  try {
			AppEngineFile file = fileService.createNewBlobFile(contentType, fileName);
			  // Open a channel to write to it
			  boolean lock = true;
			  FileWriteChannel writeChannel = fileService.openWriteChannel(file, lock);
			  ByteBuffer bb = ByteBuffer.wrap(imageData);
			  writeChannel.write(bb);
			  writeChannel.closeFinally();
			  return FileServiceFactory.getFileService().getBlobKey(file);
		} catch (IOException e) {
			e.printStackTrace();
			return null;
		}
	}


}